package com.byox.drawviewproject.slice;

import com.byox.drawview.enums.*;
import com.byox.drawview.views.DrawView;
import com.byox.drawviewproject.MyCameraAbility;
import com.byox.drawviewproject.PhotoImageAbility;
import com.byox.drawviewproject.ResourceTable;
import com.byox.drawviewproject.component.HmPopuWindow;
import com.byox.drawviewproject.dialogs.DrawAttribsDialog;
import com.byox.drawviewproject.dialogs.RequestTextDialog;
import com.byox.drawviewproject.dialogs.SaveBitmapDialog;
import com.byox.drawviewproject.moudle.ImageUri;
import com.byox.drawviewproject.moudle.PopuContentInfo;
import com.byox.drawviewproject.util.CreatPopuData;
import com.byox.drawviewproject.util.PopuValue;
import com.byox.drawviewproject.util.SimpleEventBus;
import com.github.clans.fab.FloatingActionButton;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.bundle.IBundleManager;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

import java.io.InputStream;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    private Context mContext;
    private Image muneOne, muneTwo, muneThree;
    private List<PopuContentInfo> data;
    private DrawView mDrawView;
    private FloatingActionButton mFabClearDraw;
    private HmPopuWindow hmPopuWindowThree;
    private List<PopuContentInfo> popuThreeContentInfos;
    private int[] clicked;
    private String[] popuThreeTexts;
    private Text toastText;
    private int cbInitTopMargin;
    private boolean flag = false;
    private AnimatorValue animatorValue;
    private ToastDialog toastDialog;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        getWindow().setStatusBarColor(Color.getIntColor(getString(ResourceTable.Color_typeColor)));
        initView();
        setupDrawView();
        SimpleEventBus.getSimpleEventBus().register(this);
        setListeners();
    }

    private void setupDrawView() {
        mDrawView = (DrawView) findComponentById(ResourceTable.Id_draw_view);
    }

    /**
     * onSimpleEvent方法
     *
     * @param uri 参数
     */
    public void onSimpleEvent(ImageUri uri) {
        try {
            InputStream inputStream = null;
            inputStream = DataAbilityHelper.creator(getContext()).obtainInputStream(uri.getUri());
            if (inputStream != null) {
                PixelMap pixelmap = ImageSource.create(inputStream,
                        new ImageSource.SourceOptions()).createPixelmap(new ImageSource.DecodingOptions());
                mDrawView.setBackgroundImage(pixelmap, BackgroundType.FILE, BackgroundScale.CENTER_INSIDE);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void initView() {
        this.mContext = this;
        mFabClearDraw = (FloatingActionButton) findComponentById(ResourceTable.Id_fab_clear);
        cbInitTopMargin = mFabClearDraw.getMarginBottom();
        System.out.println("cbInitTopMargin-----" + cbInitTopMargin);
        muneOne = (Image) findComponentById(ResourceTable.Id_mune_one);
        muneOne.setClickedListener(this);
        muneTwo = (Image) findComponentById(ResourceTable.Id_mune_two);
        muneTwo.setClickedListener(this);
        muneThree = (Image) findComponentById(ResourceTable.Id_mune_three);
        muneThree.setClickedListener(this);
        toastText = (Text) findComponentById(ResourceTable.Id_toastText);
        animatorValue = new AnimatorValue();
        initPopuThreeData();
    }

    private void initPopuThreeData(){
        popuThreeTexts = getStringArray(ResourceTable.Strarray_popu_three_texts);
        clicked = new int[]{1, 1};
    };

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }



    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_mune_one:
                Component componentOne = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_popu_list,
                        null, false);
                String[] popuOneTexts = getStringArray(ResourceTable.Strarray_popu_one_texts);
                List<PopuContentInfo> popuOneContentInfos = CreatPopuData.initPopuData(null, popuOneTexts, null);
                HmPopuWindow hmPopuWindowOne = new HmPopuWindow(this, componentOne, 500
                        , 400, popuOneContentInfos);
                popuOneItemClick(hmPopuWindowOne);
                hmPopuWindowOne.customShow(1);
                break;
            case ResourceTable.Id_mune_two:
                Component componentTwo = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_popu_list,
                        null, false);
                String[] popuTwoTexts = getStringArray(ResourceTable.Strarray_popu_two_texts);
                int[] images = new int[]{ResourceTable.Media_ic_action_palette, ResourceTable.Media_ic_action_image
                        , ResourceTable.Media_ic_action_brush, ResourceTable.Media_ic_action_edit
                        , ResourceTable.Media_ic_action_save, ResourceTable.Media_ic_action_photo_camera};
                List<PopuContentInfo> popuTwoContentInfos = CreatPopuData.initPopuData(images, popuTwoTexts, null);
                HmPopuWindow hmPopuWindowTwo = new HmPopuWindow(this, componentTwo, 600
                        , 1200, popuTwoContentInfos);
                popuTwoItemClick(hmPopuWindowTwo);
                hmPopuWindowTwo.customShow(2);
                break;
            case ResourceTable.Id_mune_three:
                Component componentThree = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_popu_list,
                        null, false);
                popuThreeContentInfos = CreatPopuData.initPopuData(null, popuThreeTexts, clicked);
                hmPopuWindowThree = new HmPopuWindow(this, componentThree, 500
                        , 400, popuThreeContentInfos);
                popuThreeItemClick(hmPopuWindowThree);
                hmPopuWindowThree.customShow(0);
                break;
        }
    }

    private void popuOneItemClick(HmPopuWindow hmPopuWindow) {
        hmPopuWindow.getListContainer().setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                switch (i) {
                    case PopuValue.CLEARHSITORY:
                        toastShow("action_clear_history");
                        mDrawView.clearHistory();
                        break;
                    case PopuValue.DRAWPOWER:
                        toastShow("action_switch");
                        mDrawView.setHistorySwitch(!mDrawView.getHistorySwitch());
                        break;
                }
                hmPopuWindow.destroy();
            }
        });
    }

    private void popuTwoItemClick(HmPopuWindow hmPopuWindow) {
        hmPopuWindow.getListContainer().setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                switch (i) {
                    case PopuValue.DRAWATTRIBUTES:
                        DrawAttribsDialog drawAttribsDialog = new DrawAttribsDialog(MainAbilitySlice.this
                                , null);
                        drawAttribsDialog.setPaint(mDrawView.getCurrentPaintParams());
                        drawAttribsDialog.setOnCustomViewDialogListener(new DrawAttribsDialog.OnCustomViewDialogListener() {
                            @Override
                            public void onRefreshPaint(Paint newPaint) {
                                mDrawView.setDrawColor(newPaint.getColor().getValue())
                                        .setPaintStyle(newPaint.getStyle())
                                        .setDither(newPaint.getDither())
                                        .setDrawWidth((int) newPaint.getStrokeWidth())
                                        .setDrawAlpha(newPaint.getAlpha())
                                        .setAntiAlias(newPaint.isAntiAlias())
                                        .setLineCap(newPaint.getStrokeCap())
                                        .setFontFamily(newPaint.getFont())
                                        .setFontSize(newPaint.getTextSize());
                            }
                        });
                        drawAttribsDialog.show();
                        break;
                    case PopuValue.BACKGROUNDIMAGE:
                        hmPopuWindow.destroy();
                        Intent intent = new Intent();
                        Operation operation = new Intent.OperationBuilder()
                                .withDeviceId("")
                                .withBundleName(getAbilityPackageContext().getBundleName())
                                .withAbilityName(PhotoImageAbility.class.getName())
                                .build();
                        intent.setOperation(operation);
                        verifyPermission(MainAbilitySlice.this, PopuValue.READ_MEDIA,
                                PopuValue.MY_PERMISSIONS_REQUEST_CAMERA, intent);
                        break;
                    case PopuValue.DRAWTOOL:
                        showDrawTollPopu();
                        break;
                    case PopuValue.DRAWMODE:
                        showDrawModePopu();
                        break;
                    case PopuValue.SAVEDRAW:
                        Component saveBitmap = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_save_bitmap,
                                null, false);
                        SaveBitmapDialog dialog = SaveBitmapDialog.newInstance(mContext, saveBitmap, 900
                                , ComponentContainer.LayoutConfig.MATCH_CONTENT);
                        Object[] createCaptureResponse = mDrawView.createCapture(DrawingCapture.BITMAP);
                        dialog.setPreviewBitmap((PixelMap) createCaptureResponse[0]);
                        dialog.setPreviewFormat(String.valueOf(createCaptureResponse[1]));
                        dialog.setOnSaveBitmapListener(new SaveBitmapDialog.OnSaveBitmapListener() {
                            @Override
                            public void onSaveBitmapCompleted() {
                                toastText.setText("Capture saved succesfully!");
                                showToastView();
                            }

                            @Override
                            public void onSaveBitmapCanceled() {
                                toastText.setText("Capture saved canceled.");
                                showToastView();
                            }
                        });
                        dialog.show();
                        break;
                    case PopuValue.CAMERAOPTION:
                        Intent cameraintent = new Intent();
                        Operation cameraoperation = new Intent.OperationBuilder()
                                .withDeviceId("")
                                .withBundleName(getAbilityPackageContext().getBundleName())
                                .withAbilityName(MyCameraAbility.class.getName())
                                .build();
                        cameraintent.setOperation(cameraoperation);
                        verifyPermission(mContext, PopuValue.CAMERA, PopuValue.PERMISSIONS_REQUEST_CAMERA, cameraintent);
                        break;
                }
                hmPopuWindow.destroy();
            }
        });
    }

    private void showToastView() {
        animatorValue.setDuration(200);
        if (flag) {
            animatorValue.setDelay(2500);
        }
        animatorValue.setStateChangedListener(new MyAnimationStateChange());
        animatorValue.setValueUpdateListener(new MyAnimationValueListener());
        animatorValue.start();
    }

    private class MyAnimationValueListener implements AnimatorValue.ValueUpdateListener {
        @Override
        public void onUpdate(AnimatorValue animatorValue, float v) {
            if (!flag) {
                float topMargin = (v - 1) * toastText.getHeight();
                float cbtopMargin = v * toastText.getHeight();
                toastText.setMarginBottom((int) topMargin);
                mFabClearDraw.setMarginBottom((int) (cbInitTopMargin + cbtopMargin));
            } else {
                float topMargin = -v * toastText.getHeight();
                toastText.setMarginBottom((int) topMargin);
                mFabClearDraw.setMarginBottom((int) (cbInitTopMargin + topMargin));
            }
        }
    }

    private class MyAnimationStateChange implements Animator.StateChangedListener {

        @Override
        public void onStart(Animator animator) {

        }

        @Override
        public void onStop(Animator animator) {

        }

        @Override
        public void onCancel(Animator animator) {

        }

        @Override
        public void onEnd(Animator animator) {
            if (!flag) {
                flag = true;
                showToastView();
            } else {
                flag = false;
            }
            animatorValue.setDelay(0);
            cbInitTopMargin = mFabClearDraw.getMarginBottom();
        }

        @Override
        public void onPause(Animator animator) {

        }

        @Override
        public void onResume(Animator animator) {

        }
    }

    private void canUndoRedo() {
        if (!mDrawView.canUndo()) {
            clicked[0] = 1;
        } else {
            clicked[0] = 0;
        }
        if (!mDrawView.canRedo()) {
            clicked[1] = 1;
        } else {
            clicked[1] = 0;
        }
    }

    private void setListeners() {
        mDrawView.setOnDrawViewListener(new DrawView.OnDrawViewListener() {
            @Override
            public void onStartDrawing() {
                canUndoRedo();
            }
            @Override
            public void onEndDrawing() {
                canUndoRedo();
                if (mFabClearDraw.getVisibility() == Component.INVISIBLE) {
                    mFabClearDraw.setVisibility(Component.VISIBLE);
                    handlerFabClearDraw(true, 0f, 0f, 1f, 1f);
                }
            }

            @Override
            public void onClearDrawing() {
                canUndoRedo();
                if (mFabClearDraw.getVisibility() == Component.VISIBLE) {
                    handlerFabClearDraw(false, 1f, 1f, 0f, 0f);
                }
            }

            @Override
            public void onRequestText() {
                Component component = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_request_text,
                        null, false);
                RequestTextDialog requestTextDialog = new RequestTextDialog(mContext, component, 1000
                        , ComponentContainer.LayoutConfig.MATCH_CONTENT);
                requestTextDialog.show();
                requestTextDialog.setOnRequestTextListener(new RequestTextDialog.OnRequestTextListener() {
                    @Override
                    public void onRequestTextConfirmed(String requestedText) {
                        mDrawView.refreshLastText(requestedText);
                    }
                    @Override
                    public void onRequestTextCancelled() {
                        mDrawView.cancelTextRequest();
                    }
                });
            }

            @Override
            public void onAllMovesPainted() {

            }
        });

        mFabClearDraw.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                clearDraw();
            }
        });

    }

    private void clearDraw() {
        mDrawView.restartDrawing();
    }

    private void popuThreeItemClick(HmPopuWindow hmPopuWindow) {
        hmPopuWindow.getListContainer().setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                switch (i) {
                    case PopuValue.UNDO:
                        if (mDrawView.canUndo()) {
                            mDrawView.undo();
                            canUndoRedo();
                            hmPopuWindow.destroy();
                        }
                        break;
                    case PopuValue.REDO:
                        if (mDrawView.canRedo()) {
                            mDrawView.redo();
                            canUndoRedo();
                            hmPopuWindow.destroy();
                        }
                        break;
                }

            }
        });
    }

    private void popuDrawToolItemClick(HmPopuWindow hmPopuWindow, String[] popuDrawtoolTexts) {
        hmPopuWindow.getListContainer().setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int position, long l) {
                mDrawView.setDrawingTool(DrawingTool.values()[position]);
                hmPopuWindow.destroy();
            }
        });
    }

    private void popuDrawModeItemClick(HmPopuWindow hmPopuWindow, String[] popuDrawtoolTexts) {
        hmPopuWindow.getListContainer().setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int position, long l) {
                mDrawView.setDrawingMode(DrawingMode.values()[position]);
                hmPopuWindow.destroy();
            }
        });
    }

    private void showDrawModePopu() {
        Component drawtoolComponent = LayoutScatter.getInstance(MainAbilitySlice.this).parse(ResourceTable.Layout_popu_draw_list,
                null, false);
        Text text = (Text) drawtoolComponent.findComponentById(ResourceTable.Id_text);
        text.setText("Select a draw mode");
        String[] popuDrawtoolTexts = getStringArray(ResourceTable.Strarray_popu_drawmode_texts);
        List<PopuContentInfo> popuTwoContentInfos = CreatPopuData.initPopuData(null, popuDrawtoolTexts, null);
        HmPopuWindow hmPopuWindowDrawtool = new HmPopuWindow(MainAbilitySlice.this, drawtoolComponent, 800
                , 800, popuTwoContentInfos);
        hmPopuWindowDrawtool.setAlignment(LayoutAlignment.CENTER);
        hmPopuWindowDrawtool.customShow(2);
        popuDrawModeItemClick(hmPopuWindowDrawtool, popuDrawtoolTexts);
    }

    private void showDrawTollPopu() {
        Component drawtoolComponent = LayoutScatter.getInstance(MainAbilitySlice.this).parse(ResourceTable.Layout_popu_draw_list,
                null, false);
        String[] popuDrawtoolTexts = getStringArray(ResourceTable.Strarray_popu_drawtool_texts);
        List<PopuContentInfo> popuTwoContentInfos = CreatPopuData.initPopuData(null, popuDrawtoolTexts, null);
        HmPopuWindow hmPopuWindowDrawtool = new HmPopuWindow(MainAbilitySlice.this, drawtoolComponent, 900
                , 1400, popuTwoContentInfos);
        hmPopuWindowDrawtool.setAlignment(LayoutAlignment.CENTER);
        hmPopuWindowDrawtool.customShow(2);
        popuDrawToolItemClick(hmPopuWindowDrawtool, popuDrawtoolTexts);
    }

    private void verifyPermission(Context context, String permission, int requestcode, Intent intent) {
        if (verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED) {
            // 应用未被授予权限
            if (canRequestPermission(permission)) {
                // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
                requestPermissionsFromUser(
                        new String[]{permission}, requestcode);
            } else {
                // 显示应用需要权限的理由，提示用户进入设置授权
            }
        } else {
            ((AbilitySlice) context).startAbility(intent);
        }
    }

    private void toastShow(String textStr) {
        if (toastDialog == null) {
            toastDialog = new ToastDialog(getContext());
        }
        toastDialog.setOffset(0, 200);
        toastDialog.setSize(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        toastDialog.setCornerRadius(20);
        Text text = new Text(this);
        text.setText(textStr);
        text.setTextColor(Color.DKGRAY);
        text.setTextSize(40);
        toastDialog.setComponent(text);
        toastDialog.show();
    }

    private void handlerFabClearDraw(boolean visiable, float fromScaleX, float fromScaleY, float toScaleX
            , float toScaleY) {
        mFabClearDraw.setPivot(mFabClearDraw.getWidth() / 2f, mFabClearDraw.getHeight() / 2f);
        AnimatorProperty ap = new AnimatorProperty();
        if (!visiable) {
            ap.setStateChangedListener(new Animator.StateChangedListener() {
                @Override
                public void onStart(Animator animator) {

                }

                @Override
                public void onStop(Animator animator) {

                }

                @Override
                public void onCancel(Animator animator) {

                }

                @Override
                public void onEnd(Animator animator) {
                    mFabClearDraw.setVisibility(Component.INVISIBLE);
                }

                @Override
                public void onPause(Animator animator) {

                }

                @Override
                public void onResume(Animator animator) {

                }
            });
        }
        ap.setTarget(mFabClearDraw)
                .scaleXFrom(fromScaleX).scaleYFrom(fromScaleY)
                .scaleX(toScaleX).scaleY(toScaleY)
                .setDuration(300).start();
    }
}
